import { Burst, Canvas, Component, Constructor, Layers, Node, Prefab, ResolutionPolicy, Size, UITransform, assetManager, instantiate, js, screen, view } from "cc";
import { UILayer } from "./UILayer";
import { ResLoader } from "../res/ResLoader";

const g_KeyCls2BUrl = new Map<string, IBundleUrl>();
/**注册UI */
export function registerBUrlByCfg(cfg: { [uiClassName: string]: IBundleUrl }) {
    for (let uiClassName in cfg) {
        g_KeyCls2BUrl.set(uiClassName, cfg[uiClassName]);
    }
}


const g_UICls2BUrl = new Map<any, IBundleUrl>();

/** 
 * 画布的标准化尺寸，就是之前说的
 * iPad 设备中的画布尺寸 = 1001 x 1334 (其中 1001 ≈ 1668/1.6672)
 * iPhone16设备中的画布尺寸 = 750 x1626（其中 1626 = 2556/1.572）
 */
export const G_VIEW_SIZE = new Size(0, 0);
/**
* 适配屏幕
*/
function adapterScreen(): void {
    //当前分辨率方案
    let resolutionPolicy: ResolutionPolicy = view.getResolutionPolicy();
    //视图的设计分辨率。
    let designSize: Size = view.getDesignResolutionSize();
    //获取和设置当前窗口的物理像素尺寸。
    let frameSize = screen.windowSize;
    let frameW = frameSize.width;
    let frameH = frameSize.height;
    //是否是屏幕更宽
    const isScreenWidthLarger = (frameW / frameH) > (designSize.width / designSize.height);
    //先适配小的，然后根据倍数，修改大的
    let targetResolutionPolicy = isScreenWidthLarger ? ResolutionPolicy.FIXED_HEIGHT : ResolutionPolicy.FIXED_WIDTH;
    if (targetResolutionPolicy != resolutionPolicy.getContentStrategy().strategy) {
        //保证设计分辨率的内容都能显示出来
        view.setDesignResolutionSize(designSize.width, designSize.height, targetResolutionPolicy);
        view.emit("canvas-resize");
    }

    /**实际的尺寸会和设计分辨率在一个维度，但是宽或高更大 */
    if (isScreenWidthLarger) {
        G_VIEW_SIZE.width = Math.ceil(designSize.height * frameSize.width / frameSize.height);
        G_VIEW_SIZE.height = designSize.height;
    } else {
        G_VIEW_SIZE.width = designSize.width;
        G_VIEW_SIZE.height = Math.ceil(designSize.width * frameSize.height / frameSize.width);
    }
    console.log(`屏幕${isScreenWidthLarger ? "更宽, 高度适配" : "更高, 宽度适配"}设计分辨率比例下的屏幕尺寸: ${G_VIEW_SIZE.width}x${G_VIEW_SIZE.height}`);
}

/**注册接口 */
export function setUIClassBUrl(uiClass: any, bUrl: IBundleUrl): void {
    g_UICls2BUrl.set(uiClass, bUrl);
}

/**获取接口 */
export function getUIClassBUrl(uiClass: any): IBundleUrl {
    //如果有类->BUrl的注册信息，直接拿
    if (g_UICls2BUrl.has(uiClass)) {
        return g_UICls2BUrl.get(uiClass);
    }
    //如果没有的话，从配置表拿
    let uiClassName = js.getClassName(uiClass);
    let bUrl = g_KeyCls2BUrl.get(uiClassName);
    if (!bUrl) {
        //没有找到类型对应的预制体
        debugger;
        console.error("没有找到类型对应的预制体");
        return null;
    }
    //缓存住
    g_UICls2BUrl.set(uiClass, bUrl);
    return bUrl;
}

// g_UICls2BUrl.set(Match3UI, createBundleObject("Match3UI", "Match3BN"));

class MyLayer {
    public readonly node: Node;
    constructor(public readonly layer: UILayer, public readonly canvas: Canvas, name: string) {
        const node = this.node = new Node(name);
        node.layer = Layers.Enum.UI_2D;
        node.addComponent(UITransform);
        canvas.node.addChild(node);
    }
}

/**
 * UI管理类
 */
export default class UIManager {

    private m_Canvas: Canvas = null;

    private m_Layers: MyLayer[] = [];

    // private constructor() {
    //     //私有化构造函数
    // }

    init(canvas: Canvas) {
        this.m_Canvas = canvas;
        adapterScreen();
        for (let layer = UILayer.Scene, maxLayer = UILayer.Toast; layer <= maxLayer; ++layer) {
            this.m_Layers.push(new MyLayer(layer, canvas, UILayer[layer]));
        }
    }

    /**
     * 打开界面
     * @param uiClass 
     */
    public async openUI<UI extends Component>(uiClass: Constructor<UI> & { readonly viewLayer?: UILayer }): Promise<UI> {
        //确定层级界面
        const viewLayer: UILayer = typeof (uiClass.viewLayer) == 'number' ? uiClass.viewLayer : UILayer.UI;
        const resLoader = new ResLoader();
        resLoader.addUI(uiClass);
        await resLoader.load();
        let ui = this.instantiate(uiClass);
        this.m_Layers[viewLayer].node.addChild(ui.node);
        ui.getComponent(UITransform).setContentSize(G_VIEW_SIZE.clone());
        resLoader.autoRelease(ui);
        return ui;
    }


    /**实例化节点 */
    public instantiate<UE extends Component>(ueClass: Constructor<UE>): UE {
        let bUrl = getUIClassBUrl(ueClass);
        let bundle = assetManager.getBundle(bUrl.bundleName);
        let prefab: Prefab = bundle.get(bUrl.url, Prefab);
        let node: Node = instantiate(prefab);
        return (node.getComponent(ueClass as any) || node.addComponent(ueClass as any)) as any as UE;
    }

}